import {
  VuexModule,
  Module,
  Action,
  Mutation,
  getModule
} from 'vuex-module-decorators'
import {
  login,
  logout,
  getUserInfo,
  register,
  getRegisterMsgCode,
  getSysConfig
} from '@/api/system/users'
import { getAssignedMenu } from '@/api/system/menu'
import { getToken, setToken, removeToken } from '@/utils/cookies'
import router, { resetRouter } from '@/router'
import store from '@/store'
import img from '@/assets/avatar.png'
type ISysConfig = {
  loginMethods: {
    mobile: boolean
    email: boolean
    username: boolean
  }
}
export interface IUserState {
  username: string
  name: string
  email: string
  mobile: string
  status: number
  remark: string
  create_by: string
  create_at: string
  update_by: string
  update_at: string
  avatar: any
  token: string
  menuRender: boolean
  menuTree: any[]
}

@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule implements IUserState {
  public sysConfig: ISysConfig | null = null
  public id = ''
  public username = ''
  public name = ''
  public email = ''
  public mobile = ''
  public status = 0
  public remark = ''
  public create_by = ''
  public create_at = ''
  public update_by = ''
  public update_at = ''
  public token = getToken() || ''
  public menuRender = false
  public menuRendering = false
  public menuTree = []
  public avatar = img
  @Mutation
  private SET_SYS_CONFIG(cfg: ISysConfig) {
    this.sysConfig = cfg
  }
  @Mutation
  private SET_ID(id: string) {
    this.id = id
  }
  @Mutation
  private SET_USERNAME(username: string) {
    this.username = username
  }
  @Mutation
  private SET_NAME(name: string) {
    this.name = name
  }
  @Mutation
  private SET_EMAIL(email: string) {
    this.email = email
  }
  @Mutation
  private SET_STATUS(status: number) {
    this.status = status
  }
  @Mutation
  private SET_MOBILE(mobile: string) {
    this.mobile = mobile
  }
  @Mutation
  private SET_REMARK(remark: string) {
    this.remark = remark
  }
  @Mutation
  private SET_CREATE_BY(create_by: string) {
    this.create_by = create_by
  }
  @Mutation
  private SET_CREATE_AT(create_at: string) {
    this.create_at = create_at
  }
  @Mutation
  private SET_UPDATE_BY(update_by: string) {
    this.update_by = update_by
  }
  @Mutation
  private SET_UPDATE_AT(update_at: string) {
    this.update_at = update_at
  }
  @Mutation
  private SET_AVATAR(avatar: any) {
    if (avatar) {
      this.avatar = avatar
    }
  }
  @Mutation
  private SET_TOKEN(token: string) {
    this.token = token
  }
  @Mutation
  private SET_MENURENDER(menuRender: boolean) {
    this.menuRender = menuRender
  }
  @Mutation
  private SET_MENURENDERING(menuRendering: boolean) {
    this.menuRendering = menuRendering
  }
  @Mutation
  private SET_MENUTREE(tree: []) {
    this.menuTree = tree
  }

  @Action({ rawError: true })
  public async Login(userInfo: {
    username: string
    password: string
    method: string
  }) {
    let { username, password, method } = userInfo
    username = username.trim()
    // 本地模拟
    /* if (process.env.NODE_ENV === 'production') {
      setToken('has-login')
      this.SET_TOKEN('has-login')
    } else {
      const { data } = await login({ mobile, password })
      setToken(data.uuid)
      this.SET_TOKEN(data.uuid)
    } */
    const { data } = await login({ username, password, method })
    setToken(data.uuid)
    this.SET_TOKEN(data.uuid)
  }
  @Action({ rawError: true })
  public async Register(userInfo: {
    username: string
    name: string
    email: string
    retype_password: string
    mobile: string
    password: string
  }) {
    await register(userInfo)
  }
  @Action({ rawError: true })
  public ResetToken() {
    removeToken()
    this.SET_TOKEN('')
    this.SET_MENUTREE([])
    this.ResetMenu()
    resetRouter()
  }
  @Action({ rawError: true })
  public ResetMenu() {
    this.SET_MENURENDER(false)
  }
  @Action({ rawError: true })
  public async GetMenu() {
    let accessedRouters: []
    //本地模拟
    /* if (process.env.NODE_ENV === 'production') {
      // 处理线上版本
      var data = require('./../../../public/tempMenu.js')().data
      accessedRouters = data.root.children || []
    } else {
      try {
        const { data } = await getAssignedMenu()
        accessedRouters = data.root.children || []
        this.SET_MENUTREE(accessedRouters)
        // 设置菜单是否渲染状态
        this.SET_MENURENDER(true)
      } catch (error) {
        removeToken()
        throw Error('Verification failed, please Login again.')
      }
    } */
    try {
      const { data } = await getAssignedMenu()
      accessedRouters = data.root.children || []
      this.SET_MENUTREE(accessedRouters)
      // 设置菜单是否渲染状态
      this.SET_MENURENDER(true)
    } catch (error) {
      removeToken()
      throw Error('Verification failed, please Login again.')
    }
  }
  @Action({ rawError: true })
  public setMenuRending(status: boolean) {
    this.SET_MENURENDERING(status)
  }
  @Action({ rawError: true })
  public async GetUserInfo() {
    const { data } = await getUserInfo({
      /* Your params here */
    })
    if (!data) {
      throw Error('Verification failed, please Login again.')
    }
    const {
      id,
      username,
      name,
      email,
      status,
      remark,
      mobile,
      create_by,
      create_at,
      update_by,
      update_at,
      avatar,
      uuid
    } = data
    this.SET_ID(id)
    this.SET_USERNAME(username)
    this.SET_NAME(name)
    this.SET_EMAIL(email)
    this.SET_STATUS(status)
    this.SET_MOBILE(mobile)
    this.SET_REMARK(remark)
    this.SET_CREATE_BY(create_by)
    this.SET_CREATE_AT(create_at)
    this.SET_UPDATE_BY(update_by)
    this.SET_UPDATE_AT(update_at)
    this.SET_AVATAR(avatar)
    this.SET_TOKEN(uuid)
  }

  @Action({ rawError: true })
  public async LogOut() {
    // 本地模拟
    /* if (process.env.NODE_ENV === 'production') {
      removeToken()
    } else {
      await logout()
      removeToken()
    } */
    await logout()
    removeToken()
    this.SET_TOKEN('')
    this.SET_MENUTREE([])
    this.ResetMenu()
    resetRouter()
  }

  @Action({ rawError: true })
  public async GetRegisterMsgCode(mobile: string) {
    // await new Promise(r => {
    //   setTimeout(r, 1000)
    // })
    // return
    await getRegisterMsgCode(mobile)
  }

  @Action({ rawError: true })
  public async GetSysConfig() {
    if (this.sysConfig) {
      return Promise.resolve()
    }
    const { data } = await getSysConfig()
    this.SET_SYS_CONFIG(data)
  }
}

export const UserModule = getModule(User)
